"""
数据库服务管理器
统一管理所有数据库操作，提供给API层调用
"""

from typing import List, Optional, Dict, Any
import logging
import json
import os

from .supabase_client import get_supabase_client, check_supabase_config, test_connection
from .session_dao import SessionDAO, MessageDAO, SessionModel, MessageModel
from .role_dao import RoleDAO, CustomRoleModel, RoleTrait

logger = logging.getLogger(__name__)

class DatabaseService:
    """数据库服务管理器"""
    
    def __init__(self):
        self.session_dao = None
        self.message_dao = None
        self.role_dao = None
        self._initialized = False
        
    def _init_daos(self):
        """初始化DAO对象"""
        if self.session_dao is None:
            self.session_dao = SessionDAO()
        if self.message_dao is None:
            self.message_dao = MessageDAO()
        if self.role_dao is None:
            self.role_dao = RoleDAO()
    
    def initialize(self) -> bool:
        """初始化数据库服务"""
        try:
            # 检查配置
            if not check_supabase_config():
                logger.warning("Supabase配置缺失，将使用JSON文件存储")
                return False
            
            # 测试连接
            if not test_connection():
                logger.warning("数据库连接失败，将使用JSON文件存储")
                return False
            
            # 初始化DAO对象
            self._init_daos()
            
            self._initialized = True
            logger.info("数据库服务初始化成功")
            return True
            
        except Exception as e:
            logger.error(f"数据库服务初始化失败: {e}")
            return False
    
    def is_available(self) -> bool:
        """检查数据库服务是否可用"""
        return self._initialized
    
    # === 会话相关操作 ===
    
    async def create_session(self, title: str, role_id: Optional[str] = None, 
                           model: str = 'deepseek-v3-1-250821',
                           user_id: str = '00000000-0000-0000-0000-000000000000',
                           id: Optional[str] = None, **kwargs) -> Optional[SessionModel]:
        """创建新会话"""
        if not self.is_available():
            return None
        
        try:
            return await self.session_dao.create_session(title, role_id, model, user_id, id, **kwargs)
        except Exception as e:
            logger.error(f"创建会话失败: {e}")
            return None
    
    async def get_session(self, session_id: str) -> Optional[SessionModel]:
        """获取会话"""
        if not self.is_available():
            return None
        
        return await self.session_dao.get_session(session_id)
    
    async def get_sessions(self, page: int = 1, page_size: int = 20, 
                          query: str = "", filter_type: str = "") -> Dict[str, Any]:
        """获取会话列表"""
        if not self.is_available():
            return {
                'sessions': [],
                'total': 0,
                'page': page,
                'pageSize': page_size,
                'totalPages': 0
            }
        
        return await self.session_dao.get_sessions(page, page_size, query, filter_type)
    
    async def update_session(self, session_id: str, updates: Dict[str, Any]) -> Optional[SessionModel]:
        """更新会话"""
        if not self.is_available():
            return None
        
        return await self.session_dao.update_session(session_id, updates)
    
    async def delete_session(self, session_id: str) -> bool:
        """删除会话"""
        if not self.is_available():
            return False
        
        return await self.session_dao.delete_session(session_id)
    
    # === 消息相关操作 ===
    
    async def add_message(self, session_id: str, role: str, content: str, 
                         model: Optional[str] = None, message_index: Optional[int] = None) -> Optional[MessageModel]:
        """添加消息"""
        if not self.is_available():
            return None
        
        try:
            return await self.message_dao.add_message(session_id, role, content, model, message_index)
        except Exception as e:
            logger.error(f"添加消息失败: {e}")
            return None
    
    async def get_messages(self, session_id: str) -> List[MessageModel]:
        """获取会话消息"""
        if not self.is_available():
            return []
        
        return await self.message_dao.get_messages(session_id)
    
    async def update_message(self, message_id: str, content: str) -> Optional[MessageModel]:
        """更新消息"""
        if not self.is_available():
            return None
        
        return await self.message_dao.update_message(message_id, content)
    
    async def delete_messages_after(self, session_id: str, message_index: int) -> bool:
        """删除指定消息之后的所有消息"""
        if not self.is_available():
            return False
        
        return await self.message_dao.delete_messages_after(session_id, message_index)
    
    async def get_recent_messages(self, session_id: str, limit: int = 10) -> List[MessageModel]:
        """获取最近消息"""
        if not self.is_available():
            return []
        
        return await self.message_dao.get_recent_messages(session_id, limit)
    
    # === 角色相关操作 ===
    
    async def create_custom_role(self, name: str, title: str, input_spec: str,
                               output_spec: str, custom_traits: List[RoleTrait],
                               system_prompt_snapshot: str,
                               user_id: str = '00000000-0000-0000-0000-000000000000',
                               id: Optional[str] = None, **kwargs) -> Optional[CustomRoleModel]:
        """创建自定义角色"""
        if not self.is_available():
            return None
        
        try:
            return await self.role_dao.create_custom_role(
                name, title, input_spec, output_spec, custom_traits, 
                system_prompt_snapshot, user_id, id, **kwargs
            )
        except Exception as e:
            logger.error(f"创建自定义角色失败: {e}")
            return None
    
    async def get_custom_role(self, role_id: str) -> Optional[CustomRoleModel]:
        """获取自定义角色"""
        if not self.is_available():
            return None
        
        return await self.role_dao.get_custom_role(role_id)
    
    async def get_all_custom_roles(self) -> List[CustomRoleModel]:
        """获取所有自定义角色"""
        if not self.is_available():
            return []
        
        return await self.role_dao.get_all_custom_roles()
    
    async def update_custom_role(self, role_id: str, updates: Dict[str, Any]) -> Optional[CustomRoleModel]:
        """更新自定义角色"""
        if not self.is_available():
            return None
        
        return await self.role_dao.update_custom_role(role_id, updates)
    
    async def delete_custom_role(self, role_id: str) -> bool:
        """删除自定义角色"""
        if not self.is_available():
            return False
        
        return await self.role_dao.delete_custom_role(role_id)
    
    async def increment_role_usage(self, role_id: str) -> bool:
        """增加角色使用次数"""
        if not self.is_available():
            return False
        
        return await self.role_dao.increment_usage(role_id)
    
    async def check_role_name_exists(self, name: str, exclude_id: Optional[str] = None) -> bool:
        """检查角色名称是否存在"""
        if not self.is_available():
            return False
        
        return await self.role_dao.check_role_name_exists(name, exclude_id)
    
    def get_builtin_roles(self) -> List[Dict[str, Any]]:
        """获取预设角色"""
        return self.role_dao.get_builtin_roles()
    
    # === 数据迁移相关 ===
    
    async def migrate_from_json(self, json_data_path: str) -> Dict[str, Any]:
        """从JSON文件迁移数据到数据库"""
        if not self.is_available():
            return {"success": False, "message": "数据库服务不可用"}
        
        try:
            migration_result = {
                "sessions_migrated": 0,
                "messages_migrated": 0, 
                "roles_migrated": 0,
                "errors": []
            }
            
            # 迁移会话数据
            sessions_file = os.path.join(json_data_path, "sessions.json")
            if os.path.exists(sessions_file):
                with open(sessions_file, 'r', encoding='utf-8') as f:
                    sessions_data = json.load(f)
                
                for session_id, session_data in sessions_data.items():
                    try:
                        # 检查会话是否已存在
                        existing = await self.get_session(session_id)
                        if existing:
                            continue
                        
                        # 创建会话（使用原ID）
                        session = await self.session_dao.create_session(
                            title=session_data.get('title', ''),
                            role_id=session_data.get('roleId'),
                            model=session_data.get('model', 'deepseek-v3-1-250821')
                        )
                        
                        if session:
                            migration_result["sessions_migrated"] += 1
                            
                            # 迁移该会话的消息
                            messages = session_data.get('messages', [])
                            for i, msg in enumerate(messages):
                                try:
                                    await self.message_dao.add_message(
                                        session_id=session.id,
                                        role=msg.get('role', 'user'),
                                        content=msg.get('content', ''),
                                        model=msg.get('model') if msg.get('role') == 'assistant' else None
                                    )
                                    migration_result["messages_migrated"] += 1
                                except Exception as e:
                                    migration_result["errors"].append(f"迁移消息失败 {session_id}[{i}]: {e}")
                        
                    except Exception as e:
                        migration_result["errors"].append(f"迁移会话失败 {session_id}: {e}")
            
            # 迁移角色数据
            roles_file = os.path.join(json_data_path, "roles.json")
            if os.path.exists(roles_file):
                with open(roles_file, 'r', encoding='utf-8') as f:
                    roles_data = json.load(f)
                
                for role_id, role_data in roles_data.items():
                    try:
                        # 检查角色是否已存在
                        existing = await self.get_custom_role(role_id)
                        if existing:
                            continue
                        
                        # 转换traits数据
                        traits = []
                        if 'custom_traits' in role_data:
                            for trait in role_data['custom_traits']:
                                traits.append(RoleTrait(key=trait['key'], value=trait['value']))
                        
                        # 创建角色
                        role = await self.role_dao.create_custom_role(
                            name=role_data.get('name', ''),
                            title=role_data.get('title', ''),
                            input_spec=role_data.get('input_spec', ''),
                            output_spec=role_data.get('output_spec', ''),
                            custom_traits=traits,
                            system_prompt_snapshot=role_data.get('system_prompt_snapshot', '')
                        )
                        
                        if role:
                            migration_result["roles_migrated"] += 1
                            
                    except Exception as e:
                        migration_result["errors"].append(f"迁移角色失败 {role_id}: {e}")
            
            return {
                "success": True,
                "message": "数据迁移完成",
                "data": migration_result
            }
            
        except Exception as e:
            logger.error(f"数据迁移失败: {e}")
            return {"success": False, "message": f"数据迁移失败: {e}"}

# 全局数据库服务实例（延迟初始化）
db_service = None

def get_db_service():
    """获取数据库服务实例（延迟初始化）"""
    global db_service
    if db_service is None:
        db_service = DatabaseService()
    return db_service